package roborallyimplementation;

import be.kuleuven.cs.som.annotate.*;

/**
 * This class is to be used in unison with the Position class to simplify the use of Position in a HashMap.
 * 
 * @invar	This coordinate pair can have its coordinates as coordinates.
 * 			|	isValidPair(this.getX(), this.getY())
 * @author Thomas Vochten (1ba inform), Daan Daele (1ba inform.)
 *
 */
public class CoordinatePair {
	
	/**
	 * Initializes this coordinate pair with the given x-coordinate as x-coordinate and
	 * the given y-coordinate as y-coordinate.
	 * 
	 * @param	x
	 * 			The x-coordinate of the new coordinate pair.
	 * @param	y
	 * 			The y-coordinate of the new coordinate pair.
	 * @throws	IllegalPositionException
	 * 			This coordinate pair corresponds to an illegal position.
	 * 			|	! isValidPair(x, y)
	 */
	@Raw
	public CoordinatePair(long x, long y) throws IllegalPositionException
	{
		if (! isValidPair(x, y))
			throw new IllegalPositionException("Cannot initialize a coordinate pair with negative coordinates", x, y);
		xcoord = x;
		ycoord = y;
	}
	
	/**
	 * Returns the x-coordinate of this pair.
	 *
	 */
	@Basic
	public long getX()
	{
		return xcoord;
	}
	
	/**
	 * Returns the y-coordinate of this pair.
	 *
	 */
	@Basic
	public long getY()
	{
		return ycoord;
	}
	
	/**
	 * Determines whether the given x-coordinate and y-coordinate can form a valid coordinate pair.
	 * 
	 * @param	x
	 * 			The x-coordinate to be considered.
	 * @param	y
	 * 			The y-coordinate to be considered.
	 * @return	True if and only if both x and y are positive numbers.
	 * 			|	result == x >= 0 && y >= 0
	 */
	@Raw
	public boolean isValidPair(long x, long y)
	{
		return x >= 0 && y >= 0;
	}
	
	private final long xcoord;
	private final long ycoord;
	
	/**
	 * Determines whether this coordinate pair is equal to the given object.
	 * 
	 * @param	other
	 * 			The object to be considered.
	 * @return	True if and only if other's x-coordinate and y-coordinate are equal.
	 * 			|	result == other.getX() == this.getX() && other.getY() == this.getY()
	 * @throws	IllegalArgumentException
	 * 			The given object cannot be cast to an object of class CoordinatePair.
	 * 			|	! (other instanceof CoordinatePair)
	 * 
	 */
	@Override
	public boolean equals(Object other) throws IllegalArgumentException
	{
		if (other == null)
			return false;
		if (! (other instanceof CoordinatePair))
			throw new IllegalArgumentException();
		return ((CoordinatePair)other).getX() == this.getX() && ((CoordinatePair)other).getY() == this.getY();
	}
	
	/**
	 * Calculates the hash code corresponding to this coordinate pair.
	 * 
	 * @return	Initially, the hash code equals one. Then, both coordinates are multiplied by 31
	 * 			and subsequently get added to the initial value.
	 * 			|	result == 1 + this.getX() * 31 + this.getY() * 31
	 */
	@Override @Basic
	public int hashCode()
	{
		int hash = 1;
		hash = (int) (hash + this.getX() * 31);
		hash = (int) (hash + this.getY() * 31);
		return hash;
	}
	
	/**
	 * Returns a string representation for this coordinate pair.
	 * 
	 * @return	The string representation.
	 */
	@Override
	public String toString()
	{
		return "x-coordinate = " + this.getX() + "; y-coordinate = " + this.getY();
	}
}
